/*
 * Created by JFormDesigner on Sat Jun 13 20:29:42 BST 2009
 */

package gui;

import java.awt.*;
import java.awt.event.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import execution.Manager;

import recordsDatabase.ListOfPersons;
import recordsDatabase.Person;
import resources.DateUtilities;
import resultsDatabase.Field;
import resultsDatabase.ListOfResults;
import resultsDatabase.Result;
import threads.MineThread;

/**
 * @author Alexandros Ouzounis
 */
public class WindowMineResults extends JInternalFrame {
	/**
	 * 
	 */
	private static final long serialVersionUID = 5753714888848729458L;
	private MineThread miner;
	private boolean sorting = false;
	private boolean pause = false;
	private int minedSets;
	private int totalSets;
	private DateUtilities dateTime = new DateUtilities();
	private Manager manager;
	private int clickCount = 0;
	private String stringClicked = "";

	public WindowMineResults(Manager m) {
		initComponents();
		manager = m;
		populateTheLists();
	}

	public void setMiner(MineThread m) {
		miner = m;
		if (!miner.isAlive()) {
			sortPatterns();
			double d = ((double) minedSets) / totalSets * 100;
			DecimalFormat fmt = new DecimalFormat("0.00");
			String string = fmt.format(d);
			labelSetsMine.setText("Mining canceled. Mined " + minedSets
					+ " of " + totalSets + " sets. ( " + string + "% )");
			this.repaint();
		}
	}

	private void cancelButtonMouseClicked(MouseEvent e) {
		miner.stopThreads();
		cancelButton.setEnabled(false);
		button1.setEnabled(false);
		sortPatterns();
		double d = ((double) minedSets) / totalSets * 100;
		DecimalFormat fmt = new DecimalFormat("0.00");
		String string = fmt.format(d);
		labelSetsMine.setText("Mining canceled. Mined " + minedSets + " of "
				+ totalSets + " sets. ( " + string + "% )");
		this.repaint();
	}

	private void Button1MouseClicked(MouseEvent e) {
		miner.pauseThreads();
		if (!pause) {
			button1.setText("Resume Mining");
			pause = true;
		} else {
			button1.setText("Pause Mining");
			pause = false;

		}
	}

	private void GenerateReportButtonMouseClicked(MouseEvent e) {
		if (patternsFound.size() > 0) {

			StringBuilder text = new StringBuilder();
			String newLine = "\n";
			text.append("DataMiner Generated Report");
			text.append(newLine);
			text.append(dateTime.getDateTime("yyyy.MMMMM.dd GGG hh:mm aaa"));
			text.append(newLine);
			text.append("===================================================");
			text.append(newLine);
			text.append("Fields mined: ");
			text.append(newLine);
			int i = 1;
			for (Result r : patternsFound) {
				text.append(newLine);
				text.append("------------");
				text.append(newLine);
				text.append("Result: " + i);
				text.append(newLine);
				for (Field f : r.getResultType()) {
					text.append("Category: " + f.getCategory() + " , ");
					text.append("Field: " + f.getField());
					text.append(newLine);
				}
				text.append(newLine + newLine);
				text.append("Persons: ");
				text.append(newLine + newLine);
				for (Person p : r.getPersonsList()) {
					text.append(p.getRecord("Name").getCategoryDetailsList()
							.get(0).getField());
					text.append(newLine);
				}
				i++;
			}

			// create a JFileChooser with its appropriate properties
			JFileChooser fileChooser = new JFileChooser();
			fileChooser
					.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
			int fileVal = fileChooser.showSaveDialog(generateReportButton);

			// check if the cancel button was pressed
			if (fileVal == JFileChooser.CANCEL_OPTION) {

			} else {
				// if everything is ok then get the selected file from the user
				File fileName = fileChooser.getSelectedFile();

				// if the file is empty display an error message
				if (fileName == null || fileName.getName().equals("")) {
					JOptionPane.showMessageDialog(generateReportButton,
							"Please enter a correct filename.", "Error",
							JOptionPane.ERROR_MESSAGE);
				} else

				// if the path name is OK, call the loader!
				{
					try {
						// Create file
						FileWriter fstream = new FileWriter(fileName + ".txt");
						BufferedWriter out = new BufferedWriter(fstream);
						out.write(text.toString());
						// Close the output stream
						out.close();
						JOptionPane.showMessageDialog(generateReportButton,
								"Report generated.", "Success",
								JOptionPane.INFORMATION_MESSAGE);
					} catch (Exception e1) {// Catch exception if any
						System.err.println("Error: " + e1.getMessage());
					}
				}
			}
		} else {
			JOptionPane.showMessageDialog(generateReportButton,
					"Report cannot be generated since no patterns were found.",
					"Error", JOptionPane.INFORMATION_MESSAGE);
		}

	}

	public void disableStopMiningButton() {
		cancelButton.setEnabled(false);
		cancelButton.setVisible(false);
	}

	public void disablePauseMiningButton() {
		button1.setEnabled(false);
		button1.setVisible(false);
	}

	public void pausedState() {
		button1.setText("Resume Mining");
		pause = true;
	}

	private void initComponents() {
		// JFormDesigner - Component initialization - DO NOT MODIFY
		// //GEN-BEGIN:initComponents
		// Generated using JFormDesigner Evaluation license - alex ouzounis
		dialogPane = new JPanel();
		contentPanel = new JPanel();
		bottomPanel = new JPanel();
		tabbedPane = new JTabbedPane();
		scrollPane3 = new JScrollPane();
		modelStatusPatternsFound = new DefaultListModel();
		modelStatusAllResults = new DefaultListModel();
		modelStatusInfo = new DefaultListModel();
		listPatternsFound = new JList(modelStatusPatternsFound);
		scrollPane1 = new JScrollPane();
		listAllResults = new JList(modelStatusAllResults);
		scrollPane2 = new JScrollPane();
		listInfo = new JList(modelStatusInfo);
		buttonBar = new JPanel();
		cancelButton = new JButton();
		generateReportButton = new JButton();
		button1 = new JButton();
		label1 = new JLabel();
		labelSetsMine = new JLabel();

		// ======== this ========
		setTitle("Mining Results");
		setClosable(true);
		setResizable(true);
		setMaximizable(true);
		Container contentPane = getContentPane();
		contentPane.setLayout(new BorderLayout());

		// ======== dialogPane ========
		{
			dialogPane.setBorder(new EmptyBorder(12, 12, 12, 12));

			dialogPane.setLayout(new BorderLayout());

			// ======== contentPanel ========
			{
				contentPanel.setLayout(new GridLayout(2, 1));

				// ======== tabbedPane ========
				{

					// ======== scrollPane3 ========
					{

						// ---- listPatternsFound ----
						listPatternsFound
								.addListSelectionListener(new PatternsFoundSelectionListener());
						scrollPane3.setViewportView(listPatternsFound);
					}
					tabbedPane.addTab("Patterns Found", scrollPane3);

					// ======== scrollPane1 ========
					{

						// ---- listAllResults ----
						listAllResults
								.addListSelectionListener(new AllResultsSelectionListener());
						scrollPane1.setViewportView(listAllResults);
					}
					tabbedPane.addTab("All Results", scrollPane1);

				}
				contentPanel.add(tabbedPane);

				// ======== scrollPane2 ========
				{
					listInfo.addMouseListener(new ResultsSelectionListener());
					scrollPane2.setViewportView(listInfo);
				}
				contentPanel.add(scrollPane2);
			}
			dialogPane.add(contentPanel, BorderLayout.CENTER);

			// ======== buttonBar ========
			{
				bottomPanel.setLayout(new GridLayout());
				buttonBar.setBorder(new EmptyBorder(12, 0, 0, 0));
				buttonBar.setLayout(new GridBagLayout());
				((GridBagLayout) buttonBar.getLayout()).columnWidths = new int[] {
						0, 85, 80 };
				((GridBagLayout) buttonBar.getLayout()).columnWeights = new double[] {
						1.0, 0.0, 0.0 };

				// ---- button1 ----
				button1.setText("Pause Mining");
				button1.addMouseListener(new MouseAdapter() {
					@Override
					public void mouseClicked(MouseEvent e) {
						Button1MouseClicked(e);
					}
				});
				generateReportButton.setText("Generate Report");
				generateReportButton.addMouseListener(new MouseAdapter() {
					@Override
					public void mouseClicked(MouseEvent e) {
						GenerateReportButtonMouseClicked(e);
					}
				});

				buttonBar.add(button1, new GridBagConstraints(1, 0, 1, 1, 0.0,
						0.0, GridBagConstraints.CENTER,
						GridBagConstraints.BOTH, new Insets(0, 0, 0, 5), 0, 0));

				// ---- cancelButton ----
				cancelButton.setText("Cancel Mining");
				cancelButton.addMouseListener(new MouseAdapter() {
					@Override
					public void mouseClicked(MouseEvent e) {
						cancelButtonMouseClicked(e);
					}
				});
				buttonBar.add(cancelButton, new GridBagConstraints(2, 0, 1, 1,
						0.0, 0.0, GridBagConstraints.CENTER,
						GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));

				buttonBar.add(generateReportButton, new GridBagConstraints(2,
						0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
						GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
			}
			bottomPanel.add(labelSetsMine);

			bottomPanel.add(buttonBar);

			dialogPane.add(bottomPanel, BorderLayout.SOUTH);

			// ---- label1 ----
			label1.setText("Selecte a pattern to view more information");
			dialogPane.add(label1, BorderLayout.NORTH);

		}
		contentPane.add(dialogPane, BorderLayout.CENTER);
		// //GEN-END:initComponents
	}

	public void updateMineStatus(int total, int current) {
		minedSets = current;
		totalSets = total;
		double d = ((double) current) / total * 100;
		DecimalFormat fmt = new DecimalFormat("0.00");
		String string = fmt.format(d);
		labelSetsMine.setText("Mining set " + current + " of " + total
				+ " total sets. ( " + string + "% completed.)");

	}

	private void populateTheLists() {
		ArrayList<Result> list = ListOfResults.getInstance().getResultsList();
		for (Result r : list) {
			modelStatusAllResults.addElement(r.resultFieldsToString());
			allResults.add(r);
			if (r.getPersonsList().size() > 1 & r.getResultType().size() > 1) {
				modelStatusPatternsFound.addElement(r.resultFieldsToString());
				patternsFound.add(r);
			}
		}
		if (ListOfResults.getInstance().getResultsList().size() > 1)
			sortPatterns();

	}

	private void sortPatterns() {
		sorting = true;
		listPatternsFound.setEnabled(false);
		modelStatusPatternsFound.clear();
		Collections.sort(patternsFound);
		for (Result r : patternsFound) {
			modelStatusPatternsFound.addElement(r.resultFieldsToString());
		}
		sorting = false;
		listPatternsFound.setEnabled(true);
	}

	public synchronized void addToLists(Result r) {
		modelStatusAllResults.addElement(r.resultFieldsToString());
		allResults.add(r);
		if (r.getPersonsList().size() > 1 & r.getResultType().size() > 1) {
			modelStatusPatternsFound.addElement(r.resultFieldsToString());
			patternsFound.add(r);
		}
	}

	// JFormDesigner - Variables declaration - DO NOT MODIFY
	// //GEN-BEGIN:variables
	// Generated using JFormDesigner Evaluation license - alex ouzounis
	private JPanel dialogPane;
	private JPanel contentPanel;
	private JPanel bottomPanel;
	private JTabbedPane tabbedPane;
	private JScrollPane scrollPane3;
	private JList listPatternsFound;
	private JScrollPane scrollPane1;
	private JList listAllResults;
	private JScrollPane scrollPane2;
	private JList listInfo;
	private JPanel buttonBar;
	private JButton button1;
	private JButton cancelButton;
	private JButton generateReportButton;
	private JLabel label1;
	private DefaultListModel modelStatusPatternsFound;
	private DefaultListModel modelStatusAllResults;
	private DefaultListModel modelStatusInfo;
	private ArrayList<Result> patternsFound = new ArrayList<Result>();
	private ArrayList<Result> allResults = new ArrayList<Result>();
	private JLabel labelSetsMine;

	// JFormDesigner - End of variables declaration //GEN-END:variables

	class PatternsFoundSelectionListener implements ListSelectionListener {
		public void valueChanged(ListSelectionEvent e) {
			if (!sorting) {
				// grab the result
				Result r = patternsFound.get(listPatternsFound
						.getSelectedIndex());
				modelStatusInfo.clear();
				modelStatusInfo.addElement("Result "
						+ listPatternsFound.getSelectedIndex() + ": \n");
				modelStatusInfo.addElement("\n\n\nFields: ");
				for (Field f : r.getResultType()) {
					modelStatusInfo.addElement("\n" + f.getField());
				}
				modelStatusInfo.addElement("\n\n\nPersons: ");
				for (Person p : r.getPersonsList()) {
					modelStatusInfo.addElement("\n"
							+ p.getRecord("Name").getCategoryDetailsList().get(
									0).getField());
				}
			}

		}
	}

	class AllResultsSelectionListener implements ListSelectionListener {
		public void valueChanged(ListSelectionEvent e) {
			// grab the result
			Result r = allResults.get(listAllResults.getSelectedIndex());

			modelStatusInfo.clear();
			modelStatusInfo.addElement("Result "
					+ listAllResults.getSelectedIndex() + ": \n");
			modelStatusInfo.addElement("\n\n\nFields: ");
			for (Field f : r.getResultType()) {
				modelStatusInfo.addElement("\n" + f.getField());
			}
			modelStatusInfo.addElement("\n\n\nPersons: ");
			for (Person p : r.getPersonsList()) {
				modelStatusInfo.addElement("\n"
						+ p.getRecord("Name").getCategoryDetailsList().get(0)
								.getField());
			}
		}
	}

	class ResultsSelectionListener implements MouseListener {

		public void mouseClicked(MouseEvent e) {
			if (clickCount == 0) {
				stringClicked = modelStatusInfo
						.get(listInfo.getSelectedIndex()).toString();
				clickCount++;
			} else if (clickCount == 1) {
				if (stringClicked.equalsIgnoreCase(modelStatusInfo.get(
						listInfo.getSelectedIndex()).toString())) {
					// grab the person
					String personName = modelStatusInfo.get(
							listInfo.getSelectedIndex()).toString();
					personName = personName.substring(2);
					Person newPerson = ListOfPersons.getInstance().getPerson(
							personName);
					if (newPerson != null) {
						manager.createPersonWindow(newPerson);
					}
					clickCount = 0;

				}
				clickCount = 1;
				stringClicked = modelStatusInfo
						.get(listInfo.getSelectedIndex()).toString();
			}

		}

		public void mouseEntered(MouseEvent e) {
			// TODO Auto-generated method stub

		}

		public void mouseExited(MouseEvent e) {
			// TODO Auto-generated method stub

		}

		public void mousePressed(MouseEvent e) {
			// TODO Auto-generated method stub

		}

		public void mouseReleased(MouseEvent e) {
			// TODO Auto-generated method stub

		}
	}

}
